import pytest
from fastapi.testclient import TestClient
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.pool import StaticPool
from datetime import datetime
import sys
import importlib.util
import os

# 添加路径到 sys.path
f1 = os.path.dirname(__file__)
sys.path.append(f1)
f2 = os.path.dirname(f1)
sys.path.append(f2)
                
from basic.database import get_db
from basic.models import Base
from main import app
from mock import generate_mock_data # type: ignore

# 创建测试数据库
SQLALCHEMY_DATABASE_URL = "sqlite:///:memory:"
engine = create_engine(
    SQLALCHEMY_DATABASE_URL,
    connect_args={"check_same_thread": False},
    poolclass=StaticPool,
)
TestingSessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)

# 重写依赖项
def override_get_db():
    try:
        db = TestingSessionLocal()
        yield db
    finally:
        db.close()

app.dependency_overrides[get_db] = override_get_db

# @pytest.fixture(scope="session", autouse=True)
# def setup_database():
#     # 创建所有表
#     Base.metadata.create_all(bind=engine)
#     # 生成测试数据
#     generate_mock_data(engine)
#     yield
#     # 清理数据库
#     Base.metadata.drop_all(bind=engine, use_alter=True)
generate_mock_data(engine)

@pytest.fixture
def client():
    return TestClient(app)
# pytest server/test.py -v

# pytest server/test.py::test_repos -v
def test_repos(client: TestClient):
    """
    测试获取所有仓库接口
    pytest server/test.py::test_repos -v
    """
    # 获取仓库列表
    response = client.get("/repos")
    assert response.status_code == 200
    repos = response.json()
    assert len(repos) == 2
    
    # 验证仓库信息
    repo = repos[0]
    assert "id" in repo
    assert "key" in repo
    assert "name" in repo
    assert "description" in repo
    assert "created_at" in repo
    assert "updated_at" in repo
    
    # 验证仓库列表按创建时间降序排序
    created_times = [datetime.fromisoformat(repo["created_at"]) for repo in repos]
    assert created_times == sorted(created_times, reverse=True)

# pytest server/test.py::test_repos_files -v
# curl "http://127.0.0.1:8080/repos/files?repo_key=AAAABBBBCCCCDDDD"
def test_repos_files(client: TestClient):
    """测试获取所有文件接口"""
    # 获取仓库列表
    response = client.get("/repos")
    assert response.status_code == 200
    repos = response.json()
    assert len(repos) > 0
    
    # 获取第一个仓库的文件列表
    # repo_key = repos[0]["key"]
    repo_key = "AAAABBBBCCCCDDDD"
    response = client.get("/repos/files", params={"repo_key": repo_key})
    assert response.status_code == 200
    files = response.json()
    assert len(files) == 3
    
    # 验证文件信息
    file = files[0]
    assert "name" in file
    assert "remoteKey" in file
    assert "topVersion" in file
    
    topVersion = file['topVersion']
    assert 'key' in topVersion
    assert 'versionCode' in topVersion

# pytest server/test.py::test_file_info -v
# curl "http://127.0.0.1:8080/files/info?file_key=ObzQAwQpdrsGzuGr"
def test_file_info(client: TestClient):
    """测试获取文件信息接口"""
    # 获取仓库列表
    response = client.get("/repos")
    assert response.status_code == 200
    repos = response.json()
    assert len(repos) > 0
    
    # 获取第一个仓库的文件列表
    repo_key = repos[0]["key"]
    response = client.get("/repos/files", params={"repo_key": repo_key})
    assert response.status_code == 200
    files = response.json()
    assert len(files) > 0
    
    # 获取第一个文件的信息
    file_key = files[0]["remoteKey"]
    response = client.get("/files/info", params={"file_key": file_key})
    assert response.status_code == 200
    file_info = response.json()
    
    # 验证文件信息
    assert "name" in file_info
    assert "remoteKey" in file_info
    
    assert "topVersion" in file_info
    topVersion = file_info['topVersion']
    assert 'key' in topVersion
    assert 'versionCode' in topVersion
    
    # 验证版本信息
    assert "versions" in file_info
    versions = file_info["versions"]
    assert isinstance(versions, list)
    if len(versions) > 0:
        version = versions[0]
        assert "key" in version
        assert "versionCode" in version
        assert isinstance(version["versionCode"], int)

if __name__ == "__main__":
    pytest.main([__file__]) 